<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>数字最短滚动</title>
    <link rel="stylesheet" href="./style.css" />
    <!-- <link rel="stylesheet" href="../common/normalize.css" /> -->
  </head>

  <body>
    <button class="button">数字滚动</button>
    <p><b>获取到的数字：</b><span></span></p>
    <span>请输入随机数范围</span>
    <input style="width:50px"></input>至<input style="width:50px"></input>
    <div class="num-container"></div>
  </body>
  <script>
    //获取随机数
    function genRandomNum(start,end) {
      // Math.floor()向下取整
      // 创建一个0，1000的随机数
      return Math.floor(Math.random() * (end-start)+start); //Math.random()产生一个[0，1)之间的随机数
    }
    // 计算y轴最快过渡距离
    function getFastestTranslation(start, end) {
      let direction = 1; // -1 -> scroll up | 1 -> scroll down
      let steps = 0;
      let startTansition = getNormalTranslation(start);
      // console.log(start, end, 11);
      if (start > end) {
        // start - end 为 start 向 end 递减的次数
        setDirectionAndSteps(Math.abs(start - end), Math.abs(10 - start + end));
      } else if (start < end) {
        // end - start 为 start 向 end 递减的次数
        setDirectionAndSteps(Math.abs(10 - end + start), Math.abs(end - start));
      }

      startTansition += direction * steps * step;

      /**
       * 比较上下方向，设置最短步数
       * @param {*} dstep 向下滚动的步数
       * @param {*} ustep 向上滚动的步数
       */
      // 判断滚动最短距离是向下还是向上
      // direction:滚轮移动方向 -1👆  1👇
      // step：单个数字所占的所有数字高度的分数
      // steps：移动的步数
      function setDirectionAndSteps(dstep, ustep) {
        const isUpperFaster = dstep > ustep;
        direction = isUpperFaster ? -1 : 1;
        steps = isUpperFaster ? ustep : dstep;
      }

      return `translateY(${startTansition}%)`;
    }
    // 中间区域过渡距离
    function getNormalTranslation(num) {
      // 每个 p 元素占比为100/20=5%, 第一个 0 在 25% 处出现
      return -(25 + num * 5); //此处为负数原因是要scroller向上滚动，数字向下滚动
    }
    // 复位函数
    // 如果滚轮落在了上半区或下半区，那么下一次滚动可能会不正常
    // 因此每次超出中间区就执行一次没有过渡的 translateY 将滚轮恢复到中间区
    function reposition({ style }, num) {
      const { transitionDuration } = style;
      const normalTranslation = `translateY(${getNormalTranslation(num)}%)`;
      // 判断移动的距离是否在中间区域内
      if (style.transform !== normalTranslation) {
        style.transitionDuration = "0s";
        // 直接变换到与移动距离相同的中间区域
        style.transform = normalTranslation;
        // requestAnimationFrame(
        //   requestAnimationFrame.bind(null, () => {
        setTimeout(() => {
          //在transiion里面，当连续两个duration的属性设置紧挨着时，会默认以最后一个duration属性为值,可以采用定时器的方式解决。
          style.transitionDuration = transitionDuration;
        }, 0);
        //   })
        // );
      }
    }

    const button = document.getElementsByClassName("button")[0];
    const allNum = document.querySelector("p>span");
    let numContainer = document.getElementsByClassName("num-container")[0];
    console.log(numContainer,11111)
    let input = document.getElementsByTagName("input");
    let scrollerList = document.getElementsByClassName("single-scroller");
    let step = 5; //scroller里20个数字，每个占 100/20=5%
    //存储上一次展示的数字，用于实现滚动效果
    let tempNum = [];
    button.onclick = () => {
      if(!input[0].value || !input[1].value){
        alert("请输入要摇号的随机数范围")
        return
      }
      for(let i=0;i<input[1].value.length;i++){
        tempNum.push(0)
      }
      console.log(tempNum,"111")
      const startNum=input[0].value*1
      const endNum=input[1].value*1
      allNum.innerHTML = "";
      const randomNum = genRandomNum(startNum,endNum) + "";
      // console.log(randomNum,"randomNum")
      let finishNum = randomNum.split("");
      finishNum = finishNum.map((item) => item * 1);
      numContainer.innerHTML = "";
      for (let i = 0; i < finishNum.length; i++) {
        const div = document.createElement("div");
        div.className = "scroller-window";
        div.innerHTML = `
          <div class="single-scroller">
            <p>5</p>
            <p>6</p>
            <p>7</p>
            <p>8</p>
            <p>9</p>
            <p>0</p>
            <p>1</p>
            <p>2</p>
            <p>3</p>
            <p>4</p>
            <p>5</p>
            <p>6</p>
            <p>7</p>
            <p>8</p>
            <p>9</p>
            <p>0</p>
            <p>1</p>
            <p>2</p>
            <p>3</p>
            <p>4</p>
          </div>
        `;
        numContainer.appendChild(div);
      }
      console.log(numContainer,22222)
      // console.log(numContainer, "numContainer");
      scrollerList = document.getElementsByClassName("single-scroller");
      scrollerList = Array.from(scrollerList);
      //将所有展示的元素置零：此时默认展示的是第一个元素5，将元素转移到中间0的位置
      scrollerList.forEach((scroller, index) => {
        scroller.start = tempNum[index];
        scroller.style.transform = `translateY(${getNormalTranslation(
          scroller.start
        )}%)`;
      });
      // tempNum = finishNum
      setTimeout(() => {
        scrollerList.forEach((scroller, index) => {
          // scroller.start=scroller.start?scroller.start:0;
          scroller.start = tempNum[index];
          // console.log(scroller.start, "scroller.start");
          // scroller.end = finishNum[index];
          scroller.style.transform = `translateY(${getNormalTranslation(
            scroller.start
          )}%)`;
          scroller.end = finishNum[index];
          // if (scroller.end === scroller.start) {
          //   scroller.end = diffRandomNum(scroller.end);
          // }
          allNum.innerHTML += scroller.end;
          // console.log(scroller.start, scroller.end, "se");
          scroller.style.transform = getFastestTranslation(
            scroller.start,
            scroller.end
          );
          scroller.start = scroller.end;
          //transitionend 该事件在 CSS 完成过渡后触发。
          scroller.addEventListener("transitionend", ({ target }) => {
            reposition(target, scroller.end);
          });
          tempNum = finishNum;
          console.log(tempNum, 3333);

        });
      });
    };
  </script>
</html>
